package com.whnk.pm.service.impl;

import java.io.File;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.whnk.common.config.Global;
import com.whnk.common.constant.ConfigConstants;
import com.whnk.common.utils.DateUtils;
import com.whnk.pm.domain.BaseInfo;
import com.whnk.pm.domain.EduInfo;
import com.whnk.pm.domain.FileInfo;
import com.whnk.pm.domain.ProjInfo;
import com.whnk.pm.domain.WorkInfo;
import com.whnk.pm.dto.ErrorDto;
import com.whnk.pm.mapper.BaseInfoMapper;
import com.whnk.pm.mapper.EduInfoMapper;
import com.whnk.pm.mapper.FileInfoMapper;
import com.whnk.pm.mapper.ProjInfoMapper;
import com.whnk.pm.mapper.WorkInfoMapper;
import com.whnk.pm.service.IEmpInfoImportService;
import com.whnk.pm.service.IPmCommonService;
import com.whnk.pm.util.ValidateException;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;

@Service
public class EmpInfoImportServcieImpl implements IEmpInfoImportService {
	private static final Logger log = LoggerFactory.getLogger(EmpInfoImportServcieImpl.class);
	@Autowired
	BaseInfoMapper baseInfoMapper;
	@Autowired
	EduInfoMapper eduInfoMapper;
	@Autowired
	WorkInfoMapper workInfoMapper;
	@Autowired
	ProjInfoMapper projInfoMapper;
	@Autowired
	FileInfoMapper fileInfoMapper;
	@Autowired
	IPmCommonService pmCommonServiceImpl;
	@Autowired
	private ConfigConstants configConstants;

	private List<ErrorDto> errorList = null;

	@Transactional(rollbackFor = { Exception.class }) // 手动回滚
	public void importExcel(String fileName, List<ErrorDto> errorMsg) throws Exception {
		errorList = new ArrayList<ErrorDto>();
		try {
			// 基本信息导入
			Map<String, String> empIdMap = parseBaseInfo(fileName, "基础信息");
			parseEduInfo(fileName, "教育经历", empIdMap);
			//Map<String, WorkInfo> workCompList = parseWorkInfo(fileName, "工作经历", empIdMap);
			Map<String, List<WorkInfo>> workCompList = parseWorkInfo(fileName, "工作经历", empIdMap);
			parseProjInfo(fileName, "项目经历", workCompList, empIdMap);
			if (errorList.size() > 0) {
				errorList.forEach(item -> System.out.println(item.toString()));
				log.info("校验不通过.......");
				throw new ValidateException("校验不通过.......");
			}
		} catch (ValidateException e) {
			throw new ValidateException("校验不通过.......");
		} catch (Exception e) {
			log.info("导入异常");
			log.error("error---->", e);
			throw new RuntimeException("导入异常");
		} finally {
			errorMsg.addAll(errorList);
		}
	}

	// 基本信息导入
	public Map<String, String> parseBaseInfo(String fileName, String sheetName) {
		List<List<Object>> readAll = readSheet(fileName, sheetName);
		List<BaseInfo> baseInfoList = new ArrayList<BaseInfo>();
		Map<String, String> empIdMap = new HashMap<String, String>();
		// 错误标志
		Boolean errorFlag = false;
		for (List<Object> row : readAll) {
			BaseInfo baseInfo = new BaseInfo();
			int col = 0;
			// 姓名
			baseInfo.setEmpNm(row.get(col++).toString().trim());
			// 证件类型
			baseInfo.setEmpIdType(row.get(col++).toString().trim());

			// 证件号码
			baseInfo.setEmpId(row.get(col++).toString().trim());
			// 联系电话
			baseInfo.setEmpTel(row.get(col++).toString().trim());
			// 专业技能描述
			baseInfo.setEmpSkills(row.get(col++).toString().trim());

			if (validBaseInfo(baseInfo, sheetName)) {
				errorFlag = true;
			}

			if (StringUtils.isNotEmpty(baseInfo.getEmpId())
					&& Integer.parseInt(baseInfo.getEmpId().substring(16).substring(0, 1)) % 2 == 0) {
				baseInfo.setEmpSex("女");
			} else {
				baseInfo.setEmpSex("男");
			}

			baseInfoList.add(baseInfo);
			empIdMap.put(baseInfo.getEmpId(), baseInfo.getEmpNm());
		}
		if (!errorFlag) {
			baseInfoMapper.insertBatchBaseInfo(baseInfoList);
		}
		return empIdMap;
	}

	public Boolean validBaseInfo(BaseInfo baseInfo, String sheetName) {
		Boolean errorFlag = false;
		// 检查必须输入项
		if (StringUtils.isAnyEmpty(new String[] { baseInfo.getEmpNm(), baseInfo.getEmpId(), baseInfo.getEmpIdType(),
				baseInfo.getEmpTel(), baseInfo.getEmpSkills() })) {
			errorFlag = true;
			errorList.add(new ErrorDto(baseInfo.getEmpId(), baseInfo.getEmpNm(), sheetName,
					ErrorMsgEnum.必填项检查失败.getErrorMsg()));
		}

		// 检查人员存在不支持导入
		if (StringUtils.isNotEmpty(baseInfo.getEmpId())) {
			BaseInfo temp = baseInfoMapper.selectBaseInfoById(baseInfo.getEmpId());
			if (temp != null) {
				errorFlag = true;
				errorList.add(new ErrorDto(temp.getEmpId(), temp.getEmpNm(), sheetName,
						ErrorMsgEnum.人员存在不支持导入.getErrorMsg()));
			}
		}
		return errorFlag;
	}

	// 教育经历
	public void parseEduInfo(String fileName, String sheetName, Map<String, String> empIdMap) {
		List<List<Object>> readAll = readSheet(fileName, sheetName);
		List<EduInfo> eduInfoList = new ArrayList<EduInfo>();
		Map<String, String> empIds = new HashMap<String, String>();
		for (List<Object> row : readAll) {
			EduInfo eduInfo = new EduInfo();
			int col = 0;
			// 姓名
			eduInfo.setEmpNm(row.get(col++).toString().trim());
			// *证件号码
			eduInfo.setEmpId(row.get(col++).toString().trim());
			// *毕业时间
			String empGradDt = row.get(col++).toString().trim();
			eduInfo.setEmpGradDt(empParseDate(empGradDt, "yyyyMMdd"));
			// *大学入学时间
			String empEnroDt = row.get(col++).toString().trim();
			eduInfo.setEmpEnroDt(empParseDate(empEnroDt, "yyyyMMdd"));

			// *毕业学校
			eduInfo.setEmpSch(row.get(col++).toString().trim());
			// *所学专业
			eduInfo.setEmpMajor(row.get(col++).toString().trim());
			// *专业类别
			eduInfo.setEmpMajorType(row.get(col++).toString().trim());
			// *学历
			eduInfo.setEmpEdu(row.get(col++).toString().trim());
			// *学位
			eduInfo.setEmpDeg(row.get(col++).toString().trim());

			validEduInfo(eduInfo, sheetName, empIdMap);

			eduInfoList.add(eduInfo);
			empIds.put(eduInfo.getEmpId(), "");
		}

		if (errorList.size() == 0) {
			Set<String> empIdsKeys = empIds.keySet();
			eduInfoMapper.deleteEduInfoByEmpIds(empIdsKeys.toArray(new String[empIdsKeys.size()]));
			eduInfoMapper.insertBatchEduInfo(eduInfoList);
		}

	}

	public Boolean validEduInfo(EduInfo eduInfo, String sheetName, Map<String, String> empIdMap) {
		Boolean errorFlag = false;
		// 检查必须输入项
		if (StringUtils.isAnyEmpty(new String[] { eduInfo.getEmpNm(), eduInfo.getEmpId(), eduInfo.getEmpSch(),
				eduInfo.getEmpMajor(), eduInfo.getEmpMajorType(), eduInfo.getEmpEdu() })) {
			errorFlag = true;
			errorList.add(new ErrorDto(eduInfo.getEmpId(), eduInfo.getEmpNm(), sheetName,
					ErrorMsgEnum.必填项检查失败.getErrorMsg()));
		}
		// 人员证件号码必须在基本信息中存在
		if (!empIdMap.containsKey(eduInfo.getEmpId())) {
			errorFlag = true;
			errorList.add(new ErrorDto(eduInfo.getEmpId(), eduInfo.getEmpNm(), sheetName,
					ErrorMsgEnum.人员证件号码必须在基本信息中存在.getErrorMsg()));
		}

		// 入学时间大于毕业时间
		if (eduInfo.getEmpEnroDt().after(eduInfo.getEmpGradDt())) {
			errorFlag = true;
			errorList.add(new ErrorDto(eduInfo.getEmpId(), eduInfo.getEmpNm(), sheetName,
					ErrorMsgEnum.入学时间小于毕业时间.getErrorMsg()));
		}
		return errorFlag;
	}

	public static final String 至今 = "至今";

	// 工作经历
	public Map<String, List<WorkInfo>> parseWorkInfo(String fileName, String sheetName, Map<String, String> empIdMap) {
		List<List<Object>> readAll = readSheet(fileName, sheetName);
		List<WorkInfo> workInfoList = new ArrayList<WorkInfo>();
		Map<String, List<WorkInfo>> workCompList = new HashMap<String, List<WorkInfo>>();
		String empId = null;
		String empComp = null;
		String empWorkStdt = null;
		String empWorkEddt = null;
		Map<String, String> empIds = new HashMap<String, String>();
		Map<String, String> currenWorkCompMap = new HashMap<String, String>();

		Map<String, List<WorkInfo>> workInfoListMap = new HashMap<String, List<WorkInfo>>();
		
		List<WorkInfo> works = new ArrayList<WorkInfo>();
		
		for (List<Object> row : readAll) {
			
			WorkInfo workInfo = new WorkInfo();
			int col = 0;
			// *姓名
			workInfo.setEmpNm(row.get(col++).toString().trim());
			// *证件号码
			empId = row.get(col++).toString().trim(); // *工作开始时间
			empWorkStdt = row.get(col++).toString().trim();
			// *工作结束时间
			empWorkEddt = row.get(col++).toString().trim();
			// *公司
			empComp = (String) row.get(col++);
			// 职位
			workInfo.setEmpJob(row.get(col++).toString().trim());

			workInfo.setEmpId(empId);
			workInfo.setEmpComp(empComp);
			if (至今.equals(empWorkEddt)) {
				// 对于至今的工作经历，将公司名称回写基本信息表emp_com字段
				BaseInfo baseInfo = new BaseInfo();
				baseInfo.setEmpId(empId);
				baseInfo.setEmpComp(empComp);
				baseInfoMapper.updateBaseInfo(baseInfo);
				currenWorkCompMap.put(empId, "");
			} else {
				workInfo.setEmpWorkEddt(empParseDate(empWorkEddt, "yyyyMM"));
			}
			workInfo.setEmpWorkStdt(empParseDate(empWorkStdt, "yyyyMM"));

			validWorkInfo(workInfo, sheetName, empIdMap);
			
			
			if(null == workCompList.get(empId + "-" + empComp)) {
				works = new ArrayList<WorkInfo>();
				works.add(workInfo);
				workCompList.put(empId + "-" + empComp, works);
			}
			else {
				workCompList.get(empId + "-" + empComp).add(workInfo);
			}
			
			workInfoList.add(workInfo);
			empIds.put(workInfo.getEmpId(), "");

			workInfoListMap.computeIfAbsent(workInfo.getEmpId(), key -> new ArrayList<>()).add(workInfo);
		}

		validWorkInfoDate(sheetName, empIdMap, currenWorkCompMap);
		isWorkInfoOverlap(sheetName, workInfoListMap);
		if (errorList.size() == 0) {
			Set<String> empIdsKeys = empIds.keySet();
			// workInfoMapper.deleteWorkInfoByIds(empIdsKeys.toArray(new
			// String[empIdsKeys.size()]));
			workInfoMapper.deleteWorkInfoByEmpIds(empIdsKeys.toArray(new String[empIdsKeys.size()]));
			workInfoMapper.insertBatchWorkInfo(workInfoList);
			// 统计工作年限
			pmCommonServiceImpl.staticWorkYears(workInfoListMap);
		}
		return workCompList;
	}
	
	// 工作经历
//		public Map<String, WorkInfo> parseWorkInfo(String fileName, String sheetName, Map<String, String> empIdMap) {
//			List<List<Object>> readAll = readSheet(fileName, sheetName);
//			List<WorkInfo> workInfoList = new ArrayList<WorkInfo>();
//			Map<String, WorkInfo> workCompList = new HashMap<String, WorkInfo>();
//			String empId = null;
//			String empComp = null;
//			String empWorkStdt = null;
//			String empWorkEddt = null;
//			Map<String, String> empIds = new HashMap<String, String>();
//			Map<String, String> currenWorkCompMap = new HashMap<String, String>();
//
//			Map<String, List<WorkInfo>> workInfoListMap = new HashMap<String, List<WorkInfo>>();
//
//			for (List<Object> row : readAll) {
//				WorkInfo workInfo = new WorkInfo();
//				int col = 0;
//				// *姓名
//				workInfo.setEmpNm(row.get(col++).toString().trim());
//				// *证件号码
//				empId = row.get(col++).toString().trim(); // *工作开始时间
//				empWorkStdt = row.get(col++).toString().trim();
//				// *工作结束时间
//				empWorkEddt = row.get(col++).toString().trim();
//				// *公司
//				empComp = (String) row.get(col++);
//				// 职位
//				workInfo.setEmpJob(row.get(col++).toString().trim());
//
//				workInfo.setEmpId(empId);
//				workInfo.setEmpComp(empComp);
//				if (至今.equals(empWorkEddt)) {
//					// 对于至今的工作经历，将公司名称回写基本信息表emp_com字段
//					BaseInfo baseInfo = new BaseInfo();
//					baseInfo.setEmpId(empId);
//					baseInfo.setEmpComp(empComp);
//					baseInfoMapper.updateBaseInfo(baseInfo);
//					currenWorkCompMap.put(empId, "");
//				} else {
//					workInfo.setEmpWorkEddt(empParseDate(empWorkEddt, "YYYYMM"));
//				}
//				workInfo.setEmpWorkStdt(empParseDate(empWorkStdt, "YYYYMM"));
//
//				validWorkInfo(workInfo, sheetName, empIdMap);
//
//				workCompList.put(empId + "-" + empComp, workInfo);
//				workInfoList.add(workInfo);
//				empIds.put(workInfo.getEmpId(), "");
//
//				workInfoListMap.computeIfAbsent(workInfo.getEmpId(), key -> new ArrayList<>()).add(workInfo);
//			}
//
//			validWorkInfoDate(sheetName, empIdMap, currenWorkCompMap);
//			isWorkInfoOverlap(sheetName, workInfoListMap);
//			if (errorList.size() == 0) {
//				Set<String> empIdsKeys = empIds.keySet();
//				// workInfoMapper.deleteWorkInfoByIds(empIdsKeys.toArray(new
//				// String[empIdsKeys.size()]));
//				workInfoMapper.deleteWorkInfoByEmpIds(empIdsKeys.toArray(new String[empIdsKeys.size()]));
//				workInfoMapper.insertBatchWorkInfo(workInfoList);
//				// 统计工作年限
//				pmCommonServiceImpl.staticWorkYears(workInfoListMap);
//			}
//			return workCompList;
//		}

	// 必须包含一条包含“至今”的记录
	public Boolean validWorkInfoDate(String sheetName, Map<String, String> empIdMap,
			Map<String, String> currenWorkCompMap) {
		Boolean errorFlag = false;
		for (String key : empIdMap.keySet()) {
			if (!currenWorkCompMap.containsKey(key)) {
				errorFlag = true;
				errorList.add(new ErrorDto(key, empIdMap.get(key), sheetName,
						ErrorMsgEnum.必须包含一条包含工作结束时间为至今的工作经历.getErrorMsg()));
			}
		}
		return errorFlag;
	}

	/**
	 * 任意两条工作经历的时间段不能重叠
	 * 
	 * @param sheetName
	 * @param workInfoListMap
	 * @return
	 */
	public Boolean isWorkInfoOverlap(String sheetName, Map<String, List<WorkInfo>> workInfoListMap) {
		Boolean errorFlag = false;
		for (Entry<String, List<WorkInfo>> entry : workInfoListMap.entrySet()) {
			List<WorkInfo> newSortedList = entry.getValue().stream()
					.sorted(Comparator.comparing(t -> t.getEmpWorkEddt() == null ? new Date() : t.getEmpWorkEddt()))
					.sorted(Comparator.comparing(WorkInfo::getEmpWorkStdt)).collect(Collectors.toList());

			for (int i = 0; i < newSortedList.size() - 1; i++) {
				WorkInfo workInfo1 = newSortedList.get(i);
				WorkInfo workInfo2 = newSortedList.get(i + 1);
				Date t1 = workInfo1.getEmpWorkStdt();
				Date t2 = workInfo1.getEmpWorkEddt();
				Date t3 = workInfo2.getEmpWorkStdt();
				Date t4 = workInfo2.getEmpWorkEddt();
				if (t2 != null && t1 != null && t3 != null && t4 != null && (t1.before(t2) || t1.compareTo(t2) == 0)
						&& (t3.before(t4) || t3.compareTo(t4) == 0)) {
					if (t2.compareTo(t3) > 0) {
						errorFlag = true;
						errorList.add(new ErrorDto(workInfo1.getEmpId(), workInfo1.getEmpNm(), sheetName,
								ErrorMsgEnum.任意两条工作经历的时间段不能重叠.getErrorMsg()));
						break;
					}
				}
			}
		}
		return errorFlag;
	}

	/**
	 * 
	 * @param workInfo
	 * @param sheetName
	 * @param empIdMap
	 * @return
	 */
	public Boolean validWorkInfo(WorkInfo workInfo, String sheetName, Map<String, String> empIdMap) {
		Boolean errorFlag = false;
		// 检查必须输入项
		if (StringUtils.isAnyEmpty(new String[] { workInfo.getEmpNm(), workInfo.getEmpId(), workInfo.getEmpComp() })) {
			errorFlag = true;
			errorList.add(new ErrorDto(workInfo.getEmpId(), workInfo.getEmpNm(), sheetName,
					ErrorMsgEnum.必填项检查失败.getErrorMsg()));
		}
		// 人员证件号码必须在基本信息中存在
		if (!empIdMap.containsKey(workInfo.getEmpId())) {
			errorFlag = true;
			errorList.add(new ErrorDto(workInfo.getEmpId(), workInfo.getEmpNm(), sheetName,
					ErrorMsgEnum.人员证件号码必须在基本信息中存在.getErrorMsg()));
		}

		// 工作结束时间必须大于开始时间
		Date start = workInfo.getEmpWorkStdt();
		Date end = workInfo.getEmpWorkEddt();
		if (start != null && end != null && start.after(end)) {
			errorFlag = true;
			errorList.add(new ErrorDto(workInfo.getEmpId(), workInfo.getEmpNm(), sheetName,
					ErrorMsgEnum.工作结束时间必须大于开始时间.getErrorMsg()));
		}
		try {
			pmCommonServiceImpl.eduAndWordCheck(workInfo.getEmpId(), start);
		} catch (ValidateException e) {
			errorList.add((new ErrorDto(workInfo.getEmpId(), workInfo.getEmpNm(), sheetName,
					"只需要填写毕业后的工作经历")));
		}
		return errorFlag;
	}

	/**
	 * 项目信息导入
	 * 
	 * @param fileName
	 * @param sheetName
	 * @param workCompList
	 * @param empIdMap
	 * @throws Exception
	 */
	public void parseProjInfo(String fileName, String sheetName, Map<String, List<WorkInfo>> workCompList,
			Map<String, String> empIdMap) throws Exception {

		List<List<Object>> readAll = readSheet(fileName, sheetName);
		List<ProjInfo> projInfoList = new ArrayList<ProjInfo>();
		Map<String, String> empIds = new HashMap<String, String>();
		Map<String, List<ProjInfo>> projInfoListMap = new HashMap<String, List<ProjInfo>>();
		for (List<Object> row : readAll) {
			ProjInfo projInfo = new ProjInfo();
			int col = 0;
			// *姓名
			projInfo.setEmpNm(row.get(col++).toString().trim());
			// *证件号码
			projInfo.setEmpId(row.get(col++).toString().trim());
			// *项目所属公司
			projInfo.setEmpComp(row.get(col++).toString().trim());
			// *项目名称
			projInfo.setEmpPjNm(row.get(col++).toString().trim());
			// *参与项目开始时间
			String empPjStdt = row.get(col++).toString().trim();
			projInfo.setEmpPjStdt(empParseDate(empPjStdt, "yyyyMM"));
			// *参与项目结束时间
			String empPjEddt = row.get(col++).toString().trim();
			projInfo.setEmpPjEddt(empParseDate(empPjEddt, "yyyyMM"));
			// *项目类别
			projInfo.setEmpPjType(row.get(col++).toString().trim());
			// 项目角色
			projInfo.setEmpPjRole(row.get(col++).toString().trim());
			// 责任描述
			projInfo.setEmpPjDesc(row.get(col++).toString().trim());

			checkProjPeriod(projInfo, workCompList, sheetName);
			validProjInfo(projInfo, sheetName, empIdMap);

			projInfoList.add(projInfo);
			empIds.put(projInfo.getEmpId(), "");
			projInfoListMap.computeIfAbsent(projInfo.getEmpId(), key -> new ArrayList<>()).add(projInfo);
		}

		isProjOverlap(sheetName, projInfoListMap);
		if (errorList.size() == 0) {
			Set<String> empIdsKeys = empIds.keySet();
			// projInfoMapper.deleteProjInfoByIds(empIdsKeys.toArray(new
			// String[empIdsKeys.size()]));
			projInfoMapper.deleteProjInfoByEmpIds(empIdsKeys.toArray(new String[empIdsKeys.size()]));
			projInfoMapper.insertBatchProjInfo(projInfoList);
			// 统计建行年限与建行事项个数
			pmCommonServiceImpl.staticCcbYears(projInfoListMap);
			// 统计银行年限与银行事项个数
			pmCommonServiceImpl.staticBankYears(projInfoListMap);

		}
	}
	
	
//	public void parseProjInfo(String fileName, String sheetName, Map<String, WorkInfo> workCompList,
//			Map<String, String> empIdMap) throws Exception {
//
//		List<List<Object>> readAll = readSheet(fileName, sheetName);
//		List<ProjInfo> projInfoList = new ArrayList<ProjInfo>();
//		Map<String, String> empIds = new HashMap<String, String>();
//		Map<String, List<ProjInfo>> projInfoListMap = new HashMap<String, List<ProjInfo>>();
//		for (List<Object> row : readAll) {
//			ProjInfo projInfo = new ProjInfo();
//			int col = 0;
//			// *姓名
//			projInfo.setEmpNm(row.get(col++).toString().trim());
//			// *证件号码
//			projInfo.setEmpId(row.get(col++).toString().trim());
//			// *项目所属公司
//			projInfo.setEmpComp(row.get(col++).toString().trim());
//			// *项目名称
//			projInfo.setEmpPjNm(row.get(col++).toString().trim());
//			// *参与项目开始时间
//			String empPjStdt = row.get(col++).toString().trim();
//			projInfo.setEmpPjStdt(empParseDate(empPjStdt, "YYYYMM"));
//			// *参与项目结束时间
//			String empPjEddt = row.get(col++).toString().trim();
//			projInfo.setEmpPjEddt(empParseDate(empPjEddt, "YYYYMM"));
//			// *项目类别
//			projInfo.setEmpPjType(row.get(col++).toString().trim());
//			// 项目角色
//			projInfo.setEmpPjRole(row.get(col++).toString().trim());
//			// 责任描述
//			projInfo.setEmpPjDesc(row.get(col++).toString().trim());
//
//			checkProjPeriod(projInfo, workCompList, sheetName);
//			validProjInfo(projInfo, sheetName, empIdMap);
//
//			projInfoList.add(projInfo);
//			empIds.put(projInfo.getEmpId(), "");
//			projInfoListMap.computeIfAbsent(projInfo.getEmpId(), key -> new ArrayList<>()).add(projInfo);
//		}
//
//		isProjOverlap(sheetName, projInfoListMap);
//		if (errorList.size() == 0) {
//			Set<String> empIdsKeys = empIds.keySet();
//			// projInfoMapper.deleteProjInfoByIds(empIdsKeys.toArray(new
//			// String[empIdsKeys.size()]));
//			projInfoMapper.deleteProjInfoByEmpIds(empIdsKeys.toArray(new String[empIdsKeys.size()]));
//			projInfoMapper.insertBatchProjInfo(projInfoList);
//			// 统计建行年限与建行事项个数
//			pmCommonServiceImpl.staticCcbYears(projInfoListMap);
//			// 统计银行年限与银行事项个数
//			pmCommonServiceImpl.staticBankYears(projInfoListMap);
//
//		}
//	}

	// 任意两条工作经历的时间段不能重叠
	public Boolean validProjInfo(ProjInfo projInfo, String sheetName, Map<String, String> empIdMap) {
		Boolean errorFlag = false;
		// 检查必须输入项
		if (StringUtils.isAnyEmpty(new String[] { projInfo.getEmpNm(), projInfo.getEmpId(), projInfo.getEmpComp(),
				projInfo.getEmpPjNm(), projInfo.getEmpPjType() })) {
			errorFlag = true;
			errorList.add(new ErrorDto(projInfo.getEmpId(), projInfo.getEmpNm(), sheetName,
					ErrorMsgEnum.必填项检查失败.getErrorMsg()));
		}
		// 人员证件号码必须在基本信息中存在
		if (!empIdMap.containsKey(projInfo.getEmpId())) {
			errorFlag = true;
			errorList.add(new ErrorDto(projInfo.getEmpId(), projInfo.getEmpNm(), sheetName,
					ErrorMsgEnum.人员证件号码必须在基本信息中存在.getErrorMsg()));
		}

		// 工作结束时间必须大于开始时间
		Date start = projInfo.getEmpPjStdt();
		Date end = projInfo.getEmpPjEddt();
		if (start != null && end != null && start.after(end)) {

			errorFlag = true;
			errorList.add(new ErrorDto(projInfo.getEmpId(), projInfo.getEmpNm(), sheetName,
					ErrorMsgEnum.工作结束时间必须大于开始时间.getErrorMsg()));
		}
		try {
			pmCommonServiceImpl.eduAndWordCheck(projInfo.getEmpId(), start);
		} catch (ValidateException e) {
			errorList.add((new ErrorDto(projInfo.getEmpId(), projInfo.getEmpNm(), sheetName,
					"只需要填写毕业后的项目经历")));
		}
		return errorFlag;
	}

	// public Boolean checkProjPeriod(ProjInfo projInfo,Map<String,WorkInfo>
	// workCompList,String sheetName) throws Exception {
	// //数据校验：“项目经历”中“参与项目开始时间-参与项目结束时间”需包含在对应公司“工作经历”的“工作开始时间-工作结束时间”周期范围内
	// Boolean isPassed = false;
	// WorkInfo workInfo =
	// workCompList.get(projInfo.getEmpId()+"-"+projInfo.getEmpComp());
	// if(workInfo!=null) {
	// //项目开始时间
	// if(projInfo.getEmpPjEddt()!=null && workInfo.getEmpWorkEddt()!=null) {
	// if( workInfo.getEmpWorkStdt().compareTo(projInfo.getEmpPjStdt())<=0
	// && workInfo.getEmpWorkEddt().compareTo(projInfo.getEmpPjEddt())>=0) {
	// isPassed = true;
	// }else {
	// errorList.add(new ErrorDto(projInfo.getEmpId(),projInfo.getEmpNm(),sheetName,
	// ErrorMsgEnum.项目经历时间需包含在对应公司工作经历的周期范围内.getErrorMsg()));
	// }
	// }
	//
	//
	// }else {
	// log.info("证件号码="+projInfo.getEmpId()+"对应的公司"+projInfo.getEmpComp()+"
	// 项目所属公司必须在工作经历中存在");
	// errorList.add(new
	// ErrorDto(projInfo.getEmpId(),projInfo.getEmpNm(),sheetName,ErrorMsgEnum.项目所属公司必须在工作经历中存在.getErrorMsg()));
	// }
	// return isPassed;
	// }

	public Boolean checkProjPeriod(ProjInfo projInfo, Map<String, List<WorkInfo>> workCompList, String sheetName)
			throws Exception {
		// 数据校验：“项目经历”中“参与项目开始时间-参与项目结束时间”需包含在对应公司“工作经历”的“工作开始时间-工作结束时间”周期范围内
		Boolean isPassed = false;
		
		Date empPjEddt = projInfo.getEmpPjEddt();
		if(empPjEddt == null)
			empPjEddt=empParseDate("299912", "yyyyMM");
		
		List<WorkInfo> workInfos = workCompList.get(projInfo.getEmpId() + "-" + projInfo.getEmpComp());
		if (null != workInfos && workInfos.size() > 0) {
			for (WorkInfo workInfo : workInfos) {
				
				Date empWorkEddt = workInfo.getEmpWorkEddt();
				
				if(empWorkEddt == null)
					empWorkEddt=empParseDate("299912", "yyyyMM");
				
				if (workInfo.getEmpWorkStdt().compareTo(projInfo.getEmpPjStdt()) <= 0
						&& empWorkEddt.compareTo(empPjEddt) >= 0) {
					isPassed = true;
					break;
				}
			}
			if (!isPassed) {
				errorList.add(new ErrorDto(projInfo.getEmpId(), projInfo.getEmpNm(), sheetName,
						ErrorMsgEnum.项目经历时间需包含在对应公司工作经历的周期范围内.getErrorMsg()));
			}
		} else {
			log.info("证件号码=" + projInfo.getEmpId() + "对应的公司" + projInfo.getEmpComp() + " 项目所属公司必须在工作经历中存在");
			errorList.add(new ErrorDto(projInfo.getEmpId(), projInfo.getEmpNm(), sheetName,
					ErrorMsgEnum.项目所属公司必须在工作经历中存在.getErrorMsg()));
		}

		return isPassed;
	}

	public Boolean isProjOverlap(String sheetName, Map<String, List<ProjInfo>> projInfoListMap) {
		Boolean errorFlag = false;
		for (Entry<String, List<ProjInfo>> entry : projInfoListMap.entrySet()) {
			List<ProjInfo> newSortedList = entry.getValue().stream()
					.sorted(Comparator.comparing(t -> t.getEmpPjEddt() == null ? new Date() : t.getEmpPjEddt()))
					.sorted(Comparator.comparing(ProjInfo::getEmpPjStdt)).collect(Collectors.toList());

			for (int i = 0; i < newSortedList.size() - 1; i++) {
				ProjInfo projInfo1 = newSortedList.get(i);
				ProjInfo projInfo2 = newSortedList.get(i + 1);
				Date t1 = projInfo1.getEmpPjStdt();
				Date t2 = projInfo1.getEmpPjEddt();
				Date t3 = projInfo2.getEmpPjStdt();
				Date t4 = projInfo2.getEmpPjEddt();
				if (t2 != null && t1 != null && t3 != null && t4 != null && (t1.before(t2) || t1.compareTo(t2) == 0)
						&& (t3.before(t4) || t3.compareTo(t4) == 0)) {
					if (t2.compareTo(t3) > 0) {
						errorFlag = true;
						errorList.add(new ErrorDto(projInfo1.getEmpId(), projInfo1.getEmpNm(), sheetName,
								ErrorMsgEnum.任意两条工作经历的时间段不能重叠.getErrorMsg()));
						break;
					}
				}
			}
		}
		return errorFlag;
	}

	public List<List<Object>> readSheet(String fileName, String sheetName) {
		// SHEET页
		ExcelReader reader = ExcelUtil.getReader(FileUtil.file(fileName), sheetName);
		// 总行数
		int rowCount = reader.getRowCount();
		// 固定不解析行数
		int fixDelRowCount = 0;
		return reader.read(1, rowCount - 1 - fixDelRowCount);
	}

	/**
	 * 日期型字符串转化为日期 格式
	 */
	public static Date empParseDate(Object str, String parsePatterns) {
		if (str == null) {
			return null;
		}
		try {
//			return new SimpleDateFormat(parsePatterns).parse(str.toString());
			return DateUtils.parseDate(str.toString(), parsePatterns);
		} catch (Exception e) {
			return null;
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void importImages(String zipFileName, List<String> errorMsg) throws Exception {
		log.info("开始导入-" + zipFileName);
		// File zipFileDirectory = new File(zipFileName);
		String dateStr = DateUtils.dateTimeNow();
		String targetDir = Global.getProfile() + File.separator + "images" + File.separator + dateStr;
		File targetFile = new File(targetDir);
		FileUtils.forceMkdir(targetFile);
		File outFileDir = ZipUtil.unzip(zipFileName, targetDir, Charset.forName("gbk"));
		// 目录结构 xxxx_身份证号----> 类型_01.jpg 学位证.jpg 学历证.jpg 合同.jpg
		File[] files = outFileDir.listFiles();
		for (File file : files) {
			if (file.isDirectory()) {
				String name = file.getName();
				log.info("开始导入图片信息-" + name);
				// xxxx_身份证号
				String[] empNameId = name.split("_");
				String empName = empNameId[0];
				String empId = empNameId[1];
				// 当前文件夹下所有图片信息
				File[] imagesList = file.listFiles();

				String fileNameJoin = Arrays.stream(imagesList).map(f -> f.getName()).reduce((f1, f2) -> f1 + f2)
						.orElse("");
				if (fileNameJoin.contains("身份证") && fileNameJoin.contains("学历证")
						&& (fileNameJoin.contains("合同") || fileNameJoin.contains("社保证明"))) {
				} else {
					errorMsg.add(empName + "" + empId + " 身份证、学历证必须上传;合同、社保证明至少有一个上传");
				}
				if (imagesList.length > 0) {
					// 删除原有图片信息
					fileInfoMapper.deleteFileInfoByEmpId(empId);
					for (File imageFile : imagesList) {
						String empAttType = null;
						if (imageFile.isFile()) {
							FileInfo fileInfo = new FileInfo();
							fileInfo.setEmpId(empId);
							fileInfo.setEmpNm(empName);
							fileInfo.setEmpFileNm(imageFile.getName());
							if (imageFile.getName().indexOf("_") > -1) {
								empAttType = imageFile.getName().split("_")[0];
							} else {
								empAttType = imageFile.getName().substring(0, imageFile.getName().lastIndexOf("."));
							}
							fileInfo.setEmpAttType(empAttType);
							byte[] imgbytes = FileUtils.readFileToByteArray(imageFile);
//							fileInfo.setEmpAtt(imgbytes);
							if (imgbytes != null && imgbytes.length >= 1) {
								String uuid = UUID.randomUUID().toString();
								String filePath = configConstants.getFileBaseDir() + uuid;
								com.whnk.common.utils.file.FileUtils.saveFile(imgbytes, filePath);
								fileInfo.setEmpFileId(uuid);
								fileInfo.setEmpAtt(null);
							}
							fileInfoMapper.insertFileInfo(fileInfo);
						}
					}
				}
			}

		}
		if (CollectionUtils.isNotEmpty(errorMsg)) {
			throw new ValidateException();
		}
		log.info("删除目录" + outFileDir);
		FileUtils.deleteQuietly(outFileDir);
		log.info("删除目录" + outFileDir + "成功");
		log.info(zipFileName + "导入图片信息完成");
	}

	enum ErrorMsgEnum {
		入学时间小于毕业时间("入学时间小于毕业时间"), 人员存在不支持导入("人员存在不支持导入"), 必填项检查失败("必填项检查失败"), 人员证件号码必须在基本信息中存在(
				"人员证件号码必须在基本信息中存在"), 工作结束时间必须大于开始时间("工作结束时间必须大于开始时间"), 必须包含一条包含工作结束时间为至今的工作经历(
						"必须包含一条包含工作结束时间为至今的工作经历"), 任意两条工作经历的时间段不能重叠("任意两条工作经历的时间段不能重叠"), 项目所属公司必须在工作经历中存在(
								"项目所属公司必须在工作经历中存在"), 项目经历时间需包含在对应公司工作经历的周期范围内("项目经历时间需包含在对应公司工作经历的周期范围内");
		ErrorMsgEnum(String errorMsg) {
			this.errorMsg = errorMsg;
		}

		private String errorMsg;

		public String getErrorMsg() {
			return errorMsg;
		}

		public void setErrorMsg(String errorMsg) {
			this.errorMsg = errorMsg;
		}

	}

	@Transactional(rollbackFor = { Exception.class })
	@Override
	public void importExcelProj(MultipartFile file, List<ErrorDto> errorMsg) throws Exception {
		errorList = new ArrayList<ErrorDto>();
		try {
			importProjInfo(file, "项目经历");
			if (errorList.size() > 0) {
				errorList.forEach(item -> System.out.println(item.toString()));
				log.info("校验不通过.......");
				throw new ValidateException("校验不通过.......");
			}
		} catch (ValidateException e) {
			throw new ValidateException("校验不通过.......");
		} catch (Exception e) {
			log.info("导入异常");
			log.error("error---->", e);
			throw new RuntimeException("导入异常");
		} finally {
			errorMsg.addAll(errorList);
		}
	}

	public void importProjInfo(MultipartFile file, String sheetName) throws Exception {
		ExcelReader reader = ExcelUtil.getReader(file.getInputStream(), sheetName);
		// 总行数
		int rowCount = reader.getRowCount();
		// 固定不解析行数
		int fixDelRowCount = 0;
		List<List<Object>> readAll = reader.read(1, rowCount - 1 - fixDelRowCount);
		List<ProjInfo> projInfoList = new ArrayList<ProjInfo>();
		Map<String, String> empIds = new HashMap<String, String>();
		Map<String, List<ProjInfo>> projInfoListMap = new HashMap<String, List<ProjInfo>>();

		Map<String, String> empIdMap = baseInfoMapper.selectBaseInfoList(new BaseInfo()).stream()
				.collect(Collectors.toMap(BaseInfo::getEmpId, BaseInfo::getEmpId));
		for (List<Object> row : readAll) {
			ProjInfo projInfo = new ProjInfo();
			int col = 0;
			// *姓名
			projInfo.setEmpNm(row.get(col++).toString().trim());
			// *证件号码
			projInfo.setEmpId(row.get(col++).toString().trim());
			// *项目所属公司
			projInfo.setEmpComp(row.get(col++).toString().trim());
			// *项目名称
			projInfo.setEmpPjNm(row.get(col++).toString().trim());
			// *参与项目开始时间
			String empPjStdt = row.get(col++).toString().trim();
			projInfo.setEmpPjStdt(empParseDate(empPjStdt, "yyyyMM"));
			// *参与项目结束时间
			String empPjEddt = row.get(col++).toString().trim();
			projInfo.setEmpPjEddt(empParseDate(empPjEddt, "yyyyMM"));
			// *项目类别
			projInfo.setEmpPjType(row.get(col++).toString().trim());
			// 项目角色
			projInfo.setEmpPjRole(row.get(col++).toString().trim());
			// 责任描述
			projInfo.setEmpPjDesc(row.get(col++).toString().trim());

			try {
				pmCommonServiceImpl.workProjDateCheck(projInfo);
			} catch (ValidateException e) {
				errorList.add(new ErrorDto(projInfo.getEmpId(), projInfo.getEmpNm(), sheetName,
						ErrorMsgEnum.项目经历时间需包含在对应公司工作经历的周期范围内.getErrorMsg()));
			}
			validProjInfo(projInfo, sheetName, empIdMap);
			projInfoList.add(projInfo);
			empIds.put(projInfo.getEmpId(), "");
			projInfoListMap.computeIfAbsent(projInfo.getEmpId(), key -> new ArrayList<>()).add(projInfo);
		}

		isProjOverlap(sheetName, projInfoListMap);
		if (errorList.size() == 0) {
			Set<String> empIdsKeys = empIds.keySet();
			// projInfoMapper.deleteProjInfoByIds(empIdsKeys.toArray(new
			// String[empIdsKeys.size()]));
			projInfoMapper.deleteProjInfoByEmpIds(empIdsKeys.toArray(new String[empIdsKeys.size()]));
			projInfoMapper.insertBatchProjInfo(projInfoList);
			// 统计建行年限与建行事项个数
			pmCommonServiceImpl.staticCcbYears(projInfoListMap);
			// 统计银行年限与银行事项个数
			pmCommonServiceImpl.staticBankYears(projInfoListMap);
		}
	}
}
